#ifndef __COMPAT_H
#define __COMPAT_H

#ifndef STM32F10X_MD
#define STM32F10X_MD
#define __STATIC_INLINE static inline
#define __NO_RETURN
#endif

#include "./device/stm32f10x.h"
#include <stdbool.h>

#define REG_MODIEF(REG, CLR, SET) (REG) = ((REG) & (~(CLR))) | (SET)

#define MASK1(BIT) (0x01 << (BIT))
#define MASK2(BIT) (0x03 << ((BIT) * 2))
#define MASK3(BIT) (0x07 << ((BIT) * 3))
#define MASK4(v, BIT) ((v) << ((BIT) * 4))

#define MODE_PP 0x03
#define MODE_AF_PP 0x0B
#define MODE_IN_FLOAT 0x04
#define MODE_OD 0x07
#define MODE_AIN 0x00

#define GPIO_INFO(NAME, PORT, PIN)                                             \
    static inline void NAME##_init(uint8_t mode) {                             \
        if (PIN >= 8) {                                                         \
            REG_MODIEF(PORT->CRH, MASK4(0x0F, PIN - 8), MASK4(mode, PIN - 8)); \
        } else {                                                               \
            REG_MODIEF(PORT->CRL, MASK4(0x0F, PIN), MASK4(mode, PIN));         \
        }                                                                      \
    }                                                                          \
    static inline void NAME##_set_high() { PORT->BSRR = MASK1(PIN); }          \
    static inline void NAME##_set_low() { PORT->BRR = MASK1(PIN); }            \
    static inline bool NAME##_read() { return (PORT->IDR & MASK1(PIN)) != 0; }

#endif
